import 'package:flutter/material.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:x3_component_core/x3_component_core.dart';

/// 弹窗类型
enum PeriodsType { day, week, month, year, customize }

/// 集成全部时间段选择的组件
class SelectPeriodsIntegratedComponent extends StatefulWidget {
  /// 默认选中时间标签,如果在默认标签列表里面则直接使用，否则不处理
  final BaseDateTypeEnum dateTypeEnum;

  /// 初始化开始时间 这个标签为最高级别
  final String defaultStartDate;

  /// 初始化结束时间 这个标签为最高级别
  final String defaultEndDate;

  /// 选择的类型 日/周/月/年/自定义
  final PeriodsType periodsType;

  /// 输出结果
  final Function(BaseDateTypeEnum dateTypeEnum, String showText, String startDate, String endDate) outputResult;

  /// 获取默认结果
  final Function(String label, String startDate, String endDate) initResult;

  /// 编辑显示内容 默认显示label
  final String Function(String label, DateTime startDate, DateTime endDate) editShowText;

  const SelectPeriodsIntegratedComponent({Key key, @required this.outputResult, this.initResult, this.dateTypeEnum, this.editShowText, this.periodsType = PeriodsType.customize, this.defaultStartDate, this.defaultEndDate}) : super(key: key);

  @override
  _SelectPeriodsIntegratedComponentState createState() => _SelectPeriodsIntegratedComponentState();
}

class _SelectPeriodsIntegratedComponentState extends State<SelectPeriodsIntegratedComponent> {
  /// 默认标签列表
  final List<BaseDateTypeEnum> defaultLabelList = [BaseDateTypeEnum.today, BaseDateTypeEnum.yesterday, BaseDateTypeEnum.week, BaseDateTypeEnum.lastWeek, BaseDateTypeEnum.month, BaseDateTypeEnum.lastMonth, BaseDateTypeEnum.year, BaseDateTypeEnum.lastYear];

  BaseDateTypeEnum dateTypeEnum = BaseDateTypeEnum.today;
  String showText = '请选择';
  DateTime nowDate = DateTime.now();
  DateTime startDateTime;
  DateTime endDateTime;

  @override
  void initState() {
    super.initState();
    // 校验默认标签
    checkDefaultLabel();
    // 校验开始、结束时间
    checkDefaultStartAndEnd();
  }

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: openSelectPeriodsComponent,
      child: Row(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(showText, style: TextStyle(color: Theme.of(context).textTheme.subtitle2.color)),
          SizedBox(width: 4),
          Icon(BaseIconData.x3BottomArrow, color: Theme.of(context).textTheme.subtitle2.color, size: 14),
        ],
      ),
    );
  }

  void openSelectPeriodsComponent() {
    switch (widget.periodsType) {
      case PeriodsType.day:
        onClickDayTypeEvent();
        break;
      case PeriodsType.week:
        onClickWeekEvent();
        break;
      case PeriodsType.month:
        onClickMonthEvent();
        break;
      case PeriodsType.year:
        onClickYearEvent();
        break;
      case PeriodsType.customize:
        onClickCustomizeEvent();
        break;
    }
  }

  /// 日类型的点击事件
  void onClickDayTypeEvent() {
    BaseComponentUtils.openDatePicker(context, currentDate: startDateTime, onDateChanged: (DateTime changed) {
      startDateTime = DateTime(changed.year, changed.month, changed.day);
      endDateTime = DateTime(changed.year, changed.month, changed.day, 23, 59, 59);
      bool itIsToDay = BaseDateUtil.itIsToday(startDateTime, endDateTime);
      if (itIsToDay) showText = "今天";
      bool itIsYesterday = BaseDateUtil.itIsYesterday(startDateTime, endDateTime);
      if (itIsYesterday) showText = "昨天";
      if (!itIsToDay && !itIsYesterday) {
        DateTime nowDate = DateTime.now();
        if (nowDate.year == changed.year) showText = "[${BaseTransformUtil.format(changed.month)}月${BaseTransformUtil.format(changed.day)}日]";
        if (nowDate.year != changed.year) showText = "[${changed.year}年${BaseTransformUtil.format(changed.month)}月${BaseTransformUtil.format(changed.day)}日]";
      }
      if (widget.editShowText != null) showText = widget.editShowText(showText, startDateTime, endDateTime);
      widget.outputResult(null, showText, BaseDateUtil.dateTimeAddTimeZone(startDateTime), BaseDateUtil.dateTimeAddTimeZone(endDateTime));
    });
  }

  /// 周类型的点击时间
  void onClickWeekEvent() {
    int currYear = startDateTime.year;
    int currWeek = BaseDateUtil.weekOfYear(date: startDateTime);
    BaseComponentUtils.buildBottomSheet(
      context,
      height: MediaQuery.of(context).size.height / 3,
      child: BaseSelectWeekOfYear(year: currYear, week: currWeek, selected: weekTypeSelected),
    );
  }

  /// 月类型的点击事件
  void onClickMonthEvent() {
    int currYear = startDateTime.year;
    int currMonth = startDateTime.month;
    BaseComponentUtils.buildBottomSheet(
      context,
      height: MediaQuery.of(context).size.height / 3,
      child: BaseSelectYearAndMonth(year: currYear, month: currMonth, selected: monthTypeSelected),
    );
  }

  /// 年类型的点击事件
  void onClickYearEvent() {
    int currYear = startDateTime.year;
    BaseComponentUtils.buildBottomSheet(
      context,
      height: MediaQuery.of(context).size.height / 3,
      child: BaseSelectYear(selectedAnnual: currYear, onSelected: yearTypeSelected),
    );
  }

  /// 自定义类型的点击事件
  void onClickCustomizeEvent() {
    setState(() {});
    showDialog(
        context: context,
        barrierColor: Colors.transparent,
        builder: (context) {
          return SelectPeriodsComponent(distanceToAppbar: 56.0, startDateTime: startDateTime, endDateTime: endDateTime, selectResultCallback: customizeTypeSelected);
        });
  }

  /// 周类型弹窗选择结果
  void weekTypeSelected(int year, int week) {
    List<DateTime> currWeeks = BaseDateUtil.getSomeWeek(year, week);
    bool itIsCurrWeek = BaseDateUtil.itIsCurrWeek(currWeeks[0], currWeeks[1]);
    if (itIsCurrWeek) showText = '本周';
    bool itIsLastWeek = BaseDateUtil.itIsLastWeek(currWeeks[0], currWeeks[1]);
    if (itIsLastWeek) showText = '上周';
    if (!itIsCurrWeek && !itIsLastWeek) showText = "[$year年 第$week周]";
    if (widget.editShowText != null) showText = widget.editShowText(showText, currWeeks[0], currWeeks[1]);
    startDateTime = currWeeks[0];
    endDateTime = currWeeks[1];
    widget.outputResult(null, showText, BaseDateUtil.dateTimeAddTimeZone(currWeeks[0]), BaseDateUtil.dateTimeAddTimeZone(currWeeks[1]));
    setState(() {});
  }

  /// 月类型弹窗选择结果
  void monthTypeSelected(int year, int month) {
    List<DateTime> currMonths = BaseDateUtil.getSomeMonth(year, month);
    bool itIsCurrMonth = BaseDateUtil.itIsCurrMonth(currMonths[0], currMonths[1]);
    if (itIsCurrMonth) showText = '本月';
    bool itIsLastMonth = BaseDateUtil.itIsLastMonth(currMonths[0], currMonths[1]);
    if (itIsLastMonth) showText = '上月';
    if (!itIsCurrMonth && !itIsLastMonth) showText = "[${currMonths[0].year}年${BaseTransformUtil.format(currMonths[0].month)}月]";
    if (widget.editShowText != null) showText = widget.editShowText(showText, currMonths[0], currMonths[1]);
    startDateTime = currMonths[0];
    endDateTime = currMonths[1];
    widget.outputResult(dateTypeEnum, showText, BaseDateUtil.dateTimeAddTimeZone(currMonths[0]), BaseDateUtil.dateTimeAddTimeZone(currMonths[1]));
    setState(() {});
  }

  /// 年类型弹窗选择结果
  void yearTypeSelected(int year) {
    List<DateTime> currYears = BaseDateUtil.getSomeYear(year);
    bool itIsCurrYear = BaseDateUtil.itIsCurrYear(currYears[0], currYears[1]);
    if (itIsCurrYear) showText = '本年';
    bool itIsLastYear = BaseDateUtil.itIsLastYear(currYears[0], currYears[1]);
    if (itIsLastYear) showText = '上年';
    if (!itIsCurrYear && !itIsLastYear) showText = "[${currYears[0].year}年]";
    if (widget.editShowText != null) showText = widget.editShowText(showText, currYears[0], currYears[1]);
    startDateTime = currYears[0];
    endDateTime = currYears[1];
    widget.outputResult(null, showText, BaseDateUtil.dateTimeAddTimeZone(currYears[0]), BaseDateUtil.dateTimeAddTimeZone(currYears[1]));
    setState(() {});
  }

  /// 自定义类型弹窗选择结果
  void customizeTypeSelected(BaseDateTypeEnum dateTypeEnum, String startDate, String endDate) {
    showText = BaseDateUtil.getCurrLabelForDateTypeEnum(dateTypeEnum);
    startDateTime = BaseTransformUtil.stringAsDateTime(date: startDate);
    endDateTime = BaseTransformUtil.stringAsDateTime(date: endDate);
    if (widget.editShowText != null) showText = widget.editShowText(showText, startDateTime, endDateTime);
    widget.outputResult(dateTypeEnum, showText, BaseDateUtil.dateTimeAddTimeZone(startDateTime), BaseDateUtil.dateTimeAddTimeZone(endDateTime));
    setState(() {});
  }

  /// 校验默认标
  void checkDefaultLabel() {
    if (widget.dateTypeEnum != null) {
      List<DateTime> defaultList = BaseDateUtil.getTimePeriodForDateTypeEnum(widget.dateTypeEnum);
      showText = BaseDateUtil.getCurrLabelForDateTypeEnum(widget.dateTypeEnum);
      if (widget.editShowText != null) showText = widget.editShowText(showText, defaultList[0], defaultList[0]);
      startDateTime = defaultList[0];
      endDateTime = defaultList[1];
      if (widget.initResult != null) {
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          widget.initResult(showText, BaseDateUtil.dateTimeAddTimeZone(startDateTime), BaseDateUtil.dateTimeAddTimeZone(endDateTime));
        });
      }
    }
  }

  /// 校验开始结束时间
  void checkDefaultStartAndEnd() {
    if (widget.defaultStartDate == null || widget.defaultStartDate.isEmpty) return;
    if (widget.defaultEndDate == null || widget.defaultEndDate.isEmpty) return;
    DateTime start = DateTime.tryParse(widget.defaultStartDate);
    DateTime end = DateTime.tryParse(widget.defaultEndDate);
    showText = BaseDateUtil.getCurrLabel(start, end);
    dateTypeEnum = BaseDateUtil.getCurrDateTypeEnum(start, end);
    List<DateTime> period = BaseDateUtil.getTimePeriodForDateTypeEnum(dateTypeEnum);
    if (period.length != 2) return;
    startDateTime = period[0];
    endDateTime = period[1];
    if (widget.initResult != null) {
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        widget.initResult(showText, BaseDateUtil.dateTimeAddTimeZone(startDateTime), BaseDateUtil.dateTimeAddTimeZone(endDateTime));
      });
    }
  }
}
